/*
@file: libCommon.cpp
@author: ZZH
@date: 2023-02-03
@info: 动态库公共部分
*/
#include <cmath>
#include <cstring>
#include "libCommon.h"

void normalize(BasicType* output, BasicType* buf, unsigned int len)
{
    if (nullptr == buf || 0 == len)
        return;

    BasicType sum = 0;

    for (unsigned int i = 0;i < len;i++)
        sum += buf[i];

    if (0 != sum)
    {
        for (unsigned int i = 0;i < len;i++)
            output[i] = buf[i] / sum;
    }
}

void swap_arr(BasicType* output, BasicType* buf, unsigned int len)
{
    if (nullptr == buf || nullptr == output || 0 == len)
        return;

    unsigned half_len = len / 2;

    for (int i = 0;i < half_len;i++)
    {
        BasicType tmp = buf[i];
        output[i] = buf[half_len + i];
        output[half_len + i] = tmp;
    }
}

void hamming(BasicType* buf, unsigned int len)
{
    if (nullptr == buf || len < 2)
        return;

    const BasicType arg = M_PI * 2 / (len - 1);

    for (unsigned int i = 0;i < len;i++)
        buf[i] = 0.54 - 0.46 * cos(i * arg);
}

//完整卷积, 会计算卷积核超出数据的部分
void full_conv(BasicType* output, BasicType* arr1, size_t len1, BasicType* arr2, size_t len2)
{
    if (len2 > len1 || len1 == 0 || len2 == 0)
        return;

    if (nullptr == output || nullptr == arr1 || nullptr == arr2)
        return;

    const size_t outSize = len1 + len2 - 1;
    // memset(output, 0, sizeof(BasicType) * outSize);

    for (size_t i = 0;i < outSize;i++)//总的计算次数
    {
        size_t j = i < len2 ? len2 - i - 1 : 0;//第二个数组的取数起始下标
        size_t cont = i > len1 - 1 ? outSize - i : len2;//循环次数控制结尾阶段
        size_t ii = i < len2 ? 0 : i - len2 + 1;//第一个数组的取数起始下标
        BasicType res = 0;
        
        for (;j < cont;j++, ii++)
            res += arr1[ii] * arr2[j];

        output[i] = res;
    }
}

//有效卷积, 仅计算双方完全重合时的部分
void valid_conv(BasicType* output, BasicType* arr1, size_t len1, BasicType* arr2, size_t len2)
{
    if (len2 > len1 || len1 == 0 || len2 == 0)
        return;

    if (nullptr == output || nullptr == arr1 || nullptr == arr2)
        return;

    const size_t outSize = len1 - len2 + 1;
    // memset(output, 0, sizeof(BasicType) * outSize);

    for (size_t i = 0;i < outSize;i++)//总的计算次数
    {
        size_t ii = i;//第一个数组的取数起始下标
        BasicType res = 0;

        for (size_t j = 0;j < len2;j++, ii++)
            res += arr1[ii] * arr2[j];

        output[i] = res;
    }
}
